#include "commmsg.h"
#include "commerrno.h"
#include "../cmd/dataprepare.h"
#include "../clan/CClanMgr.h"
#include "../clan/CClanTreeMgr.h"
#include "../cmd/cmdapi.h"
#include "../storage/CStorageMgr.h"
#include "cmdclan.h"

CT_REGISTER_ASYNCCMD(ID_MAIN_CLAN_OPER, CCmdClanOper);
int CCmdClanOper::Do(void* pData)
{
    CT_ASSERT(pData);

    //解析消息
    CCmdPBDoParam* pstParam = (CCmdPBDoParam*) pData;
    pstMainCtrl = (CMainCtrl*) pstParam->m_pMain;

    if (pstParam->m_pstMsgHead->msgid() != ID_MAIN_CLAN_OPER ||
        pstParam->m_pstMsgHead->msgtype() != CSMsgDef::EMT_REQUEST)
    {
        CT_ERROR(("Cmd Stat Err Cmd=%d CmdID=%d Type=%d",
            ID_MAIN_CLAN_OPER,
            pstParam->m_pstMsgHead->msgid(),
            pstParam->m_pstMsgHead->msgtype()));
        return Done(RET_SYS_ERROR);
    }

    stMsgHead = *(pstParam->m_pstMsgHead);
    stEnpHead = *(pstParam->m_pstEnpHead);
    int iRet = pstMainCtrl->DecodePBMsg(stReq, pstParam);
    if (iRet)
    {
        return AnsClients(iRet);
    }
    //消息解析结束

    uiGID = (unsigned int)stReq.gid();

    //检查登录
    iRet = pstMainCtrl->CheckLogin(uiGID, stEnpHead);
    if (iRet != RET_OK)
    {
        return AnsClients(iRet);
    }

    LogicDo(RET_OK);
    return RET_OK;
}

int CCmdClanOper::LogicDo(int iRet)
{
    if (iRet)
    {
        return AnsClients(iRet);
    }

    PREPARE_PLAYER_BASE_INFO(this, uiGID);
    PREPARE_PLAYER_DETAIL_INFO(this, uiGID);
    PREPARE_PLAYER_SNS_DETAIL_INFO(this, uiGID);
    PREPARE_PLAYER_DETAIL_EX1_INFO(this, uiGID);
    PREPARE_PLAYER_ONLINE_DATA(this, uiGID);

    //要处理的对象不在线时,要从数据库中拉出来
    unsigned int uiOperGid = (unsigned int)stReq.oper_gid();  //审批加入申请
    if (0 != uiOperGid)
    {
        PREPARE_PLAYER_DETAIL_INFO(this, uiOperGid);
        PREPARE_PLAYER_SNS_DETAIL_INFO(this, uiOperGid);
    }

    int iIndex = pstMainCtrl->m_stPlayerBaseInfoHash.HashFind(uiGID);
    if (iIndex < 0)
    {
        return AnsClients(RET_NO_USER);
    }
    CPlayerBaseInfo& stPlayerBaseInfo = pstMainCtrl->m_stPlayerBaseInfoHash[iIndex];

    if (stPlayerBaseInfo._ucIsInited != 1)
    {
        return AnsClients(ERROR_NOT_INITED);
    }

    iIndex = pstMainCtrl->m_stPlayerDetailInfoHash.HashFind(uiGID);
    if (iIndex < 0)
    {
        return AnsClients(RET_NO_USER);
    }
    CPlayerDetailInfo & stPlayerDetailInfo = pstMainCtrl->m_stPlayerDetailInfoHash[iIndex];

    iIndex = pstMainCtrl->m_stPlayerDetailEx1InfoHash.HashFind(uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("get user detail ex1 info error, uid = %u", uiGID));
        return AnsClients(RET_SYSTEM_FAIL);
    }
    CPlayerDetailInfoEx1& stPlayerDetailEx1Info = pstMainCtrl->m_stPlayerDetailEx1InfoHash[iIndex];

    iIndex = pstMainCtrl->m_stPlayerOnlineDataHash.HashFind(uiGID);
    if (iIndex < 0)
    {
        return AnsClients(RET_NO_USER);
    }
    CPlayerOnlineData& stPlayerOnlineData = pstMainCtrl->m_stPlayerOnlineDataHash[iIndex];

    iIndex = pstMainCtrl->m_stPlayerSnsDetailInfoHash.HashFind(uiGID);
    if (iIndex < 0)
    {
        return AnsClients(RET_NO_USER);
    }
    CPlayerSnsDetailInfo & stPlayerSnsDetailInfo = pstMainCtrl->m_stPlayerSnsDetailInfoHash[iIndex];

    //检查系统是否开启
    if (!pstMainCtrl->m_stCommConfigLoader.IsOpen(SYS_OPEN_COND_ID_11, stPlayerBaseInfo, stPlayerOnlineData))
    {
        return AnsClients(ERROR_SYS_NOT_OPEN);
    }

    if (0 != stPlayerDetailInfo._stUserClan._uiClanId)
    {
        //家族被解散了. 清空sns和detail中数据
        if (pstMainCtrl->m_stClanMgr.GetClanIndexByClanId(stPlayerDetailInfo._stUserClan._uiClanId) < 0)
        {
            stPlayerDetailInfo._stUserClan.ClearWhenNoClan();
            stPlayerSnsDetailInfo._stCommInfo._uiClanId = 0;
            UpdatePlayerData(uiGID, UPDATE_DETAIL_INFO | UPDATE_SNS_INFO);
        }
    }

    pstMainCtrl->m_stClanMgr.CheckAndSortClan ();

    unsigned char ucOperType = (unsigned char)(stReq.oper_type() & 0x7F);
    if (uiGID == uiOperGid)
    {
        CT_ERROR(("%d, %d", uiGID, ucOperType));
        return AnsClients(ERROR_CLAN_OPER_MYSELF);
    }

    unsigned char ucMyUpdateInfo = 0;
    unsigned char ucOtherUpdateInfo = 0;
    uiClanId = (unsigned int)stReq.clan_id();

    CTSizeString<MAX_CLAN_NOTICE_STRING_LEN> szMsg;
    szMsg.Set("%s", stReq.clan_name().c_str());

    if (CLAN_REQ_CREATE_CLAN == ucOperType &&
        pstMainCtrl->m_stZoneOnlineData._stZoneData._chStopCreateClan > 0)
    {
        return AnsClients(ERROR_SYS_STOP_CREATE_CLAN);
    }

    if (CLAN_REQ_CREATE_CLAN == ucOperType || CLAN_CHANGE_NOTICE == ucOperType)
    {
        if (m_pstChild && ID_MAINAPI_TAPI == m_pstChild->GetCmdID())
        {
            CCmdApi* pstCmd = (CCmdApi*)m_pstChild;
            if (pstCmd->stReq._szTApiName == "/v3/csec/word_filter")
            {
                bool bIsDirty = ((atoi(pstCmd->stAns._stTApiKeyValue.GetValue("is_dirty")) != 0) ? true : false);
                if (bIsDirty)
                {
                    if (CLAN_REQ_CREATE_CLAN == ucOperType)
                    {
                        return AnsClients(ERROR_HAS_SEN_WORD);
                    }

                    if (CLAN_CHANGE_NOTICE == ucOperType)
                    {
                        if (strcmp("文本中有敏感词", pstCmd->stAns._stTApiKeyValue.GetValue("msg")) == 0)
                        {
                            return AnsClients(ERROR_HAS_SEN_WORD);
                        }
                        else
                        {
                            szMsg.Set("%s", pstCmd->stAns._stTApiKeyValue.GetValue("msg"));
                        }
                    }
                }
            }
        }

        if (!_bHasCheckMsg)
        {
            _bHasCheckMsg = true;

            //检查长度，处理屏蔽字
            iRet = pstMainCtrl->m_stClanMgr.CheckString (szMsg(), szMsg.GetDataLen());
            if (iRet != RET_OK)
            {
                return AnsClients(iRet);
            }

            if (szMsg.GetDataLen() != 0 && stPlayerOnlineData._bIsTencentLogin)
            {
                //在平台检查
                CCmdApi* pstCmd = (CCmdApi*)CT_CMDFACTORY->CreateCmd(ID_MAINAPI_TAPI);
                if (!pstCmd)
                {
                    CT_WARNING(("create cmd error"));
                    return AnsClients(RET_SYS_ERROR);
                }

                pstCmd->pstMainCtrl = CMainCtrl::m_pstMain;
                pstCmd->stReq._ucReqType = CReqApi::API_TENCENT;
                pstCmd->stReq._szTApiName.Set("/v3/csec/word_filter");
                pstCmd->stReq._stTApiKeyValue = stPlayerOnlineData._stTencentApiKeyValue;
                pstCmd->stReq._stTApiKeyValue.SetValue("content", szMsg());

                uint64 u64MsgID = CT_UINT64_MAKE(uiGID, pstMainCtrl->m_iNow);
                pstCmd->stReq._stTApiKeyValue.SetValue("msgid", CTStringUtils::Uint64ToString(u64MsgID, 16));

                RegisterChild(pstCmd, true);
                return pstCmd->Do(NULL);
            }
        }
    }

    switch (ucOperType)
    {
    case CLAN_REQ_CREATE_CLAN:  //创建家族
        {
            iRet = pstMainCtrl->m_stClanMgr.CreateClan(stPlayerBaseInfo, stPlayerDetailInfo._stUserClan, szMsg(), szMsg.GetDataLen());
            if (RET_OK == iRet)
            {
                uiClanId = stPlayerDetailInfo._stUserClan._uiClanId;

                ucMyUpdateInfo = UPDATE_BASE_INFO | UPDATE_DETAIL_INFO | UPDATE_SNS_INFO;

                uiNotify = NOTIFY_USER_MONEY;

                GetClanInfo();

                //触发任务
                pstMainCtrl->m_stTaskMgr.TriggerDoSomeOpt(stPlayerOnlineData._stUserTask, TASK_OPT_ID_114, 1); //加入或创建一个家族
            }

            CT_INFO (("gid :%u create clan: %u, ret: %d.", uiGID, uiClanId, iRet));
        }
        break;

    case CLAN_REQ_DELETE_CLAN:  //解散家族
        {
            iRet = pstMainCtrl->m_stClanMgr.DeleteClan(uiGID, stPlayerDetailInfo._stUserClan, uiClanId);

            //延迟解散时,通知前台解散倒计时间
            int iIndex = pstMainCtrl->m_stClanMgr._stClanEntryHash.HashFind(uiClanId);
            if (iIndex >= 0)
            {
                MsgClanDetailInfo * pstDetailInfo = stAns.mutable_clan_detail_info();
                pstMainCtrl->m_stClanMgr.GetClanDetailInfo (uiClanId, (*pstDetailInfo));
                stAns.set_para1(pstDetailInfo->expired_time());
                CT_INFO (("gid :%u delete clan: %u, ret: %u. time: %d", uiGID, uiClanId, iRet, pstDetailInfo->expired_time()));
            }
            else
            {
                ucMyUpdateInfo = UPDATE_DETAIL_INFO | UPDATE_SNS_INFO;

                stAns.set_para1(0);
                CT_INFO (("gid :%u delete clan: %u, ret: %u.", uiGID, uiClanId, iRet));
            }
        }
        break;

    case CLAN_REQ_JOIN_CLAN:  //请求加入
        {
            iRet = pstMainCtrl->m_stClanMgr.RequestJoinClan(stPlayerBaseInfo, uiClanId, stPlayerDetailInfo._stUserClan);
            CT_INFO (("gid :%u request join clan: %u, ret: %u.", uiGID, uiClanId, iRet));

            ucMyUpdateInfo = UPDATE_DETAIL_INFO;

            SendInfoToFront(SEND_CLAN_PENDING, 0);
        }
        break;

    case CLAN_CANCEL_JOIN_REQ:  //取消申请
        {
            iRet = pstMainCtrl->m_stClanMgr.CancelJoinRequest(uiGID, stPlayerDetailInfo._stUserClan, uiClanId);
            CT_INFO (("gid :%u cancel join clan: %u request, ret: %u.", uiGID, uiClanId, iRet));

            ucMyUpdateInfo = UPDATE_DETAIL_INFO;

            SendInfoToFront(SEND_CLAN_PENDING, 0);
        }
        break;

    case CLAN_JOIN_REQ_ACCEPT:    //接受申请
    case CLAN_JOIN_REQ_REJECT:    //拒绝申请
        {
            iIndex = pstMainCtrl->m_stPlayerDetailInfoHash.HashFind(uiOperGid);
            if (iIndex < 0)
            {
                return AnsClients(ERROR_CLAN_OPER_USER_NOT_EXIST);
            }
            CUserClan & stUserClan = pstMainCtrl->m_stPlayerDetailInfoHash[iIndex]._stUserClan;

            uiClanId = stPlayerDetailInfo._stUserClan._uiClanId;
            iRet = pstMainCtrl->m_stClanMgr.HandleJoinRequest(uiGID, uiClanId, stUserClan, uiOperGid, ucOperType);
            CT_INFO (("gid :%u handle clan: %u , obj_gid: %u, ret: %u.", uiGID, uiClanId, uiOperGid, iRet));
            if (RET_OK == iRet)
            {
                if (CLAN_JOIN_REQ_ACCEPT == ucOperType)
                {
                    SendInfoToFront(SEND_CLAN_MEMBER, 0);

                    NotifyOther(uiOperGid, ucOperType);
                    ucOtherUpdateInfo = UPDATE_DETAIL_INFO | UPDATE_SNS_INFO;

                    //触发任务
                    iIndex = pstMainCtrl->m_stPlayerOnlineDataHash.HashFind(uiOperGid);
                    if (iIndex >= 0)
                    {
                        CPlayerOnlineData& stDestPlayerOnlineData = pstMainCtrl->m_stPlayerOnlineDataHash[iIndex];
                        pstMainCtrl->m_stTaskMgr.TriggerDoSomeOpt(stDestPlayerOnlineData._stUserTask, TASK_OPT_ID_114, 1); //加入或创建一个家族
                    }
                }

                if (CLAN_JOIN_REQ_REJECT == ucOperType)
                {
                    SendInfoToFront(SEND_JOIN_REQ, uiOperGid);
                    ucOtherUpdateInfo = UPDATE_DETAIL_INFO;
                }
            }
        }
        break;

    case CLAN_REQ_QUIT_CLAN:  //请求退出
        {
            uiClanId = stPlayerDetailInfo._stUserClan._uiClanId;
            iRet = pstMainCtrl->m_stClanMgr.QuitClan(uiGID, stPlayerDetailInfo._stUserClan);
            CT_INFO (("gid :%u quit clan: %u, ret: %u.", uiGID, uiClanId, iRet));
            if (RET_OK == iRet)
            {
                SendInfoToFront(SEND_CLAN_MEMBER, uiGID);

                ucMyUpdateInfo = UPDATE_DETAIL_INFO | UPDATE_SNS_INFO;
            }
        }
        break;

    case CLAN_FORCE_QUIT_CLAN:   //强制踢出
        {
            iIndex = pstMainCtrl->m_stPlayerDetailInfoHash.HashFind(uiOperGid);
            if (iIndex < 0)
            {
                return AnsClients(ERROR_CLAN_OPER_USER_NOT_EXIST);
            }
            CUserClan & stOutUser = pstMainCtrl->m_stPlayerDetailInfoHash[iIndex]._stUserClan;

            uiClanId = stPlayerDetailInfo._stUserClan._uiClanId;
            iRet = pstMainCtrl->m_stClanMgr.ForceQuitClan(uiGID, stOutUser, uiOperGid);

            if (RET_OK == iRet)
            {
                SendInfoToFront(SEND_CLAN_MEMBER, 0);

                ucOtherUpdateInfo = UPDATE_DETAIL_INFO | UPDATE_SNS_INFO;
            }
        }
        break;

    case CLAN_TRANS_LEADER_TITLE:  //族长转让
        {
            iRet = pstMainCtrl->m_stClanMgr.TransferClan(uiGID, uiClanId, uiOperGid);
            if (RET_OK == iRet)
            {
                uiNotify = NOTIFY_ROLE_INFO;
                GetClanInfo ();
            }
        }
        break;

    case CLAN_APPOINT_TITLE:      //职务任命
        {
            unsigned char ucNewTitle = (unsigned char)(stReq.oper_para() & 0x7f);
            iRet = pstMainCtrl->m_stClanMgr.AppointTitle (uiGID, stPlayerDetailInfo._stUserClan, uiOperGid, ucNewTitle);
            if (RET_OK == iRet)
            {
                uiNotify = NOTIFY_ROLE_INFO;
                SendInfoToFront(SEND_CLAN_MEMBER, 0);
            }
        }
        break;

    case CLAN_UPGRADE_CLAN:       //家族升级
        {
            iRet = pstMainCtrl->m_stClanMgr.UpgradeClan(uiGID, stPlayerDetailInfo._stUserClan);
            if (RET_OK == iRet)
            {
                uiClanId = stPlayerDetailInfo._stUserClan._uiClanId;
                SendInfoToFront(SEND_CLAN_INFO, uiClanId);
            }
        }
        break;

    case CLAN_DONATE_CLAN:      //家族捐献
        {
            uiClanId = stPlayerDetailInfo._stUserClan._uiClanId;
            iRet = pstMainCtrl->m_stClanMgr.Donate(stPlayerBaseInfo, stPlayerDetailInfo, stPlayerSnsDetailInfo, stReq.oper_para(), stReq.donate_silver());
            if (iRet)
            {
                return AnsClients(iRet);
            }

            uiNotify = NOTIFY_USER_MONEY | NOTIFY_ROLE_INFO;

            if (stReq.oper_para() > 0)
            {
                uiNotify |= NOTIFY_BAG_INFO;
            }

            //触发任务
            CMainCtrl::m_pstMain->m_stDailyTaskMgr.TriggerTaskFinish(stPlayerOnlineData._stUserDailyTask, DAILY_TASK_ID_30);
            pstMainCtrl->m_stTaskMgr.TriggerDoSomeOpt(stPlayerOnlineData._stUserTask, TASK_OPT_ID_125, 1);

            ucMyUpdateInfo = UPDATE_BASE_INFO | UPDATE_SNS_INFO;
            uiFillAns = FILL_ANS_MEMBER | FILL_ANS_BASE;
        }
        break;

    case CLAN_LEARN_SKILL:   //学习家族技能
        {
            //检查系统是否开启
            if (!pstMainCtrl->m_stCommConfigLoader.IsOpen(SYS_OPEN_COND_ID_27, stPlayerBaseInfo, stPlayerOnlineData))
            {
                return AnsClients(ERROR_SYS_NOT_OPEN);
            }

            uiClanId = stPlayerDetailInfo._stUserClan._uiClanId;
            unsigned char ucSkillId = stReq.oper_para();
            iRet = pstMainCtrl->m_stClanMgr.LearnSkill(ucSkillId, stPlayerDetailInfo._stUserClan,
                stPlayerSnsDetailInfo._stCommInfo._iContribution, uiGID);
            if (iRet)
            {
                return AnsClients(iRet);
            }

            //重新计算主角和所有伙伴的属性
            iIndex = pstMainCtrl->m_stPlayerOnlineDataHash.HashFind(uiGID);
            if (iIndex < 0)
            {
                return AnsClients(RET_NOT_LOGIN);
            }

            CPlayerOnlineData & stPlayerOnlineData = pstMainCtrl->m_stPlayerOnlineDataHash[iIndex];

            //主角重新计算后会下发一次阵形战斗力给前端因此放在伙伴计算的后面
            uiNotify |= NOTIFY_PARTNER_ATTR;
            uiNotify |= NOTIFY_ROLE_ATTR;

            uiNotify |= NOTIFY_ROLE_INFO;
            uiFillAns = FILL_ANS_MEMBER;
            ucMyUpdateInfo = UPDATE_BASE_INFO | UPDATE_SNS_INFO;

            //触发任务
            pstMainCtrl->m_stTaskMgr.TriggerDoSomeOpt(stPlayerOnlineData._stUserTask, TASK_OPT_ID_115, 1); //学习一次家族技能

            //新手目标
            for (int i = 0; i < stPlayerDetailInfo._stUserClan._astClanSkill.Size(); i++)
            {
                if (stPlayerDetailInfo._stUserClan._astClanSkill[i]._ucType == ucSkillId)
                {
                    pstMainCtrl->m_stNewbieTaskMgr.Trigger(stPlayerDetailEx1Info._stNewbieTaskUserData, uiGID, NEWBIE_TASK_COND_6,
                        stPlayerDetailInfo._stUserClan._astClanSkill[i]._iValue);
                    break;
                }
            }
        }
        break;

    case CLAN_IGNORE_ALL_REQ:   //忽略所有加入家族
        {
            uiClanId = stPlayerDetailInfo._stUserClan._uiClanId;

            //检查家族是否存在
            int iClanIndex = pstMainCtrl->m_stClanMgr._stClanEntryHash.HashFind(uiClanId);
            if (iClanIndex < 0)
            {
                return AnsClients(ERROR_CLAN_NOT_EXIST);
            }
            CClanEntry & stClanEntry = pstMainCtrl->m_stClanMgr._stClanEntryHash[iClanIndex];

            iRet = pstMainCtrl->m_stClanMgr.CheckPermission(uiGID, stClanEntry, CLAN_JOIN_REQ_REJECT);
            if (iRet)
            {
                return AnsClients(iRet);
            }

            while (stClanEntry._astJoinReq.Size() > 0)
            {
                int iReqIndex = stClanEntry._astJoinReq.Size() - 1;
                unsigned int uiReqGid = stClanEntry._astJoinReq[iReqIndex];

                PREPARE_PLAYER_DETAIL_INFO(this, uiReqGid);

                int iIndex = pstMainCtrl->m_stPlayerDetailInfoHash.HashFind(uiReqGid);
                if (iIndex < 0)
                {
                    continue;
                }
                CUserClan & stReqUserClan = pstMainCtrl->m_stPlayerDetailInfoHash[iIndex]._stUserClan;

                iRet = pstMainCtrl->m_stClanMgr.CancelJoinRequest (uiReqGid, stReqUserClan, stClanEntry._uiClanId);
                if (iRet)
                {
                    CT_ERROR(("Gid: %u, clanid: %u", uiReqGid, stClanEntry._uiClanId));
                    continue;
                }

                UpdatePlayerData (uiReqGid, UPDATE_DETAIL_INFO);
                SendInfoToFront(SEND_JOIN_REQ, uiReqGid);
            }

            CT_INFO (("gid :%u cancel join clan: %u request, ret: %u.", uiGID, uiClanId, iRet));
        }
        break;

    case CLAN_CHANGE_NOTICE:    //更改家族公告
        {
            uiClanId = stPlayerDetailInfo._stUserClan._uiClanId;
            int iLen = szMsg.GetDataLen();
            iRet = pstMainCtrl->m_stClanMgr.ChangeNotice (uiGID, uiClanId, szMsg(), iLen);
            if (RET_OK == iRet)
            {
                uiFillAns = FILL_ANS_DETAIL;
            }
        }
        break;

    case CLAN_CANCEL_DELETE:   //取消家族解散
        {
            uiClanId = stPlayerDetailInfo._stUserClan._uiClanId;
            iRet = pstMainCtrl->m_stClanMgr.CancelDelete(uiGID, stPlayerDetailInfo._stUserClan, uiClanId);
            if (RET_OK == iRet)
            {
                MsgClanDetailInfo * pstDetailInfo = stAns.mutable_clan_detail_info();
                pstMainCtrl->m_stClanMgr.GetClanDetailInfo (uiClanId, (*pstDetailInfo));
            }
        }
        break;

    case CLAN_ALLOT_BONUS :
        {
            if (stReq.clan_members_size() <= 0 || stReq.clan_members_size() > MAX_CLAN_BONUS_MEMBER
                || stReq.items_size() <= 0 || stReq.items_size() > MAX_CLAN_BONUS_COUNT)
            {
                CT_ERROR(("%d, %d", stReq.clan_members_size(), stReq.items_size()));
                return AnsClients(ERROR_CLAN_PARA_INVALID);
            }

            uiClanId = stPlayerDetailInfo._stUserClan._uiClanId;
            iRet = pstMainCtrl->m_stClanMgr.AllocBonus(uiGID, uiClanId);
            if (iRet)
            {
                return AnsClients(iRet);
            }

            CCmdClanBonus * pstCmd = (CCmdClanBonus*)CT_CMDFACTORY->CreateCmd(ID_MAIN_INNER_CLAN_BONUS);
            if (!pstCmd)
            {
                CT_WARNING(("create CCmdClanBonus error"));
                return Done(RET_SYSTEM_FAIL);
            }

            pstCmd->pstMainCtrl = pstMainCtrl;
            pstCmd->_uiClanId = uiClanId;
            pstCmd->_stReq = stReq;
            RegisterChild(pstCmd);
            iRet = pstCmd->Do(NULL);
            return 0;
        }
        break;

    case CLAN_SEND_RECRUIT:
        {
            uiClanId = stPlayerDetailInfo._stUserClan._uiClanId;
            iRet = pstMainCtrl->m_stClanMgr.Recruit(stPlayerBaseInfo, stPlayerDetailInfo._stUserClan);
            if (RET_OK == iRet)
            {
                ucMyUpdateInfo |= UPDATE_BASE_INFO;
                uiFillAns |= FILL_ANS_BASE;
            }
        }
        break;

    default:
        return AnsClients(ERROR_CLAN_PARA_INVALID);
    }

    if (iRet)
    {
        return AnsClients(iRet);
    }

    //数据入库
    UpdateClanData(uiClanId, ucOperType);
    UpdatePlayerData (uiGID, ucMyUpdateInfo);
    if (0 != uiOperGid)
    {
        UpdatePlayerData (uiOperGid, ucOtherUpdateInfo);
        NotifyOther(uiOperGid, ucOperType);
    }

    return AnsClients(RET_OK);
}

void CCmdClanOper::NotifyOther (unsigned int uiGid, unsigned int ucOperType)
{
    if (!pstMainCtrl->m_stPlayerOnline.CheckOnline(uiGid))
    {
        return ;
    }

    PBMsgHead stMsgHeader;
    stMsgHeader.set_msgret(0);
    stMsgHeader.set_msgact(0);
    stMsgHeader.set_msgid(ID_MAIN_CLAN_OPER);
    stMsgHeader.set_msgtype(CSMsgDef::EMT_ANSWER);

    MsgAnsClanOper stAnsOper;
    stAnsOper.set_oper_type(ucOperType);
    stAnsOper.set_para1(uiClanId);
    if (CLAN_FORCE_QUIT_CLAN != ucOperType)
    {
        int iIndex = pstMainCtrl->m_stClanMgr._stClanEntryHash.HashFind(uiClanId);
        if (iIndex < 0)
        {
            CT_ERROR(("%d", uiClanId));
            return ;
        }
        CClanEntry & stClanEntry = pstMainCtrl->m_stClanMgr._stClanEntryHash[iIndex];

        iIndex = pstMainCtrl->m_stPlayerDetailInfoHash.HashFind(uiGid);
        if (iIndex < 0)
        {
            CT_ERROR(("%d", uiGid));
            return ;
        }
        CPlayerDetailInfo & stPlayerDetailInfo = pstMainCtrl->m_stPlayerDetailInfoHash[iIndex];

        pstMainCtrl->m_stClanMgr.GetClanBaseInfo (stClanEntry, stPlayerDetailInfo._stUserClan, (*(stAnsOper.mutable_clan_base_info())));
        pstMainCtrl->m_stClanMgr.GetClanDetailInfo (uiClanId, (*(stAnsOper.mutable_clan_detail_info())));
    }

    pstMainCtrl->m_stEncodeBuf.Clear();
    pstMainCtrl->EncodePBMsg(stMsgHeader, pstMainCtrl->m_stEncodeBuf);
    pstMainCtrl->EncodePBMsg(stAnsOper, pstMainCtrl->m_stEncodeBuf);
    pstMainCtrl->NotifyOnlineUser(uiGid, pstMainCtrl->m_stEncodeBuf);

    if (CLAN_TRANS_LEADER_TITLE == ucOperType
        || CLAN_APPOINT_TITLE == ucOperType
        || CLAN_JOIN_REQ_ACCEPT == ucOperType)
    {
        pstMainCtrl->m_stNotifyMgr.Notify(uiGid, NOTIFY_ROLE_INFO);
    }
}

void CCmdClanOper::UpdatePlayerData (unsigned int uiGid, unsigned char ucType)
{
    if (uiGid == 0)
    {
        return ;
    }

    CVarObjectKey stKey;
    stKey.m_u64ID = uiGid;

    if (UPDATE_BASE_INFO & ucType)
    {
        int iIndex = pstMainCtrl->m_stPlayerBaseInfoHash.HashFind(uiGid);
        if (iIndex < 0)
        {
            CT_ERROR(("%d", uiGid));
            return ;
        }
        CPlayerBaseInfo & stPlayerBaseInfo = pstMainCtrl->m_stPlayerBaseInfoHash[iIndex];
        stKey.m_chDataType = DT_PLAYER_BASE_INFO;
        pstMainCtrl->UpdateData(stKey, stPlayerBaseInfo, VOP_UPDATE);
    }

    if (UPDATE_DETAIL_INFO & ucType)
    {
        int iIndex = pstMainCtrl->m_stPlayerDetailInfoHash.HashFind(uiGid);
        if (iIndex < 0)
        {
            CT_ERROR(("%d", uiGid));
            return ;
        }
        CPlayerDetailInfo & stPlayerDetailInfo = pstMainCtrl->m_stPlayerDetailInfoHash[iIndex];
        stKey.m_chDataType = DT_PLAYER_DETAIL_INFO;
        pstMainCtrl->UpdateData(stKey, stPlayerDetailInfo, VOP_UPDATE);
    }

    if (UPDATE_SNS_INFO & ucType)
    {
        int iIndex = pstMainCtrl->m_stPlayerSnsDetailInfoHash.HashFind(uiGid);
        if (iIndex < 0)
        {
            CT_ERROR(("%d", uiGid));
            return ;
        }
        CPlayerSnsDetailInfo& stPlayerSnsDetailInfo = pstMainCtrl->m_stPlayerSnsDetailInfoHash[iIndex];

        stKey.m_chDataType = DT_PLAYER_SNS_DETAIL_INFO;
        pstMainCtrl->UpdateData(stKey, stPlayerSnsDetailInfo, VOP_UPDATE);
    }

    return ;
}

void CCmdClanOper::UpdateClanData(unsigned int uiClanId, unsigned char ucOperType)
{
    CVarObjectKey stKey;
    CClanData stClanData;
    stKey.m_chDataType = DT_CLAN_DATA;
    stKey.m_u64ID = uiClanId;

    if (CLAN_REQ_DELETE_CLAN != ucOperType)
    {
        int iIndex = pstMainCtrl->m_stClanMgr._stClanEntryHash.HashFind(uiClanId);
        if (iIndex < 0)
        {
            CT_ERROR(("Update clan not exist. %d", uiClanId));
            return ;
        }

        pstMainCtrl->m_stClanMgr.GetClanData(pstMainCtrl->m_stClanMgr._stClanEntryHash[iIndex], stClanData);
        pstMainCtrl->UpdateData(stKey, stClanData, (CLAN_REQ_CREATE_CLAN == ucOperType ? VOP_CREATE : VOP_UPDATE));
    }

    return ;
}

int CCmdClanOper::AnsClients(int iRet)
{
    if (uiNotify)
    {
        pstMainCtrl->m_stNotifyMgr.Notify(uiGID, uiNotify);
    }

    stMsgHead.set_msgret(iRet);
    stMsgHead.set_msgtype(CSMsgDef::EMT_ANSWER);

    if (iRet != RET_OK)
    {
        pstMainCtrl->ReturnMsgHead(stMsgHead, stEnpHead);
        return Done(iRet);
    }

    stAns.set_oper_type(stReq.oper_type());
    pstMainCtrl->m_stEncodeBuf.Clear();
    pstMainCtrl->EncodePBMsg(stMsgHead, pstMainCtrl->m_stEncodeBuf);

    if (FILL_ANS_MEMBER & uiFillAns)
    {
        pstMainCtrl->m_stClanMgr.GetClanMemberInfo(uiClanId, uiGID, (*stAns.mutable_member_info()));
    }

    if (FILL_ANS_BASE & uiFillAns)
    {
        int iIndex = pstMainCtrl->m_stClanMgr._stClanEntryHash.HashFind(uiClanId);
        if (iIndex >= 0)
        {
            int iIndex2 = pstMainCtrl->m_stPlayerDetailInfoHash.HashFind(uiGID);
            if (iIndex2 >= 0)
            {
                pstMainCtrl->m_stClanMgr.GetClanBaseInfo(pstMainCtrl->m_stClanMgr._stClanEntryHash[iIndex],
                    pstMainCtrl->m_stPlayerDetailInfoHash[iIndex2]._stUserClan, (*stAns.mutable_clan_base_info()));
            }
        }
    }

    if (FILL_ANS_DETAIL & uiFillAns)
    {
        pstMainCtrl->m_stClanMgr.GetClanDetailInfo(uiClanId, (*stAns.mutable_clan_detail_info()));
    }

    pstMainCtrl->EncodePBMsg(stAns, pstMainCtrl->m_stEncodeBuf);
    if (pstMainCtrl->AnswerToClient(stEnpHead, pstMainCtrl->m_stEncodeBuf,true))
    {
        CT_WARNING((""));
        return Done(RET_SYS_ERROR);
    }

    //需要家族数据先入库才下发活动列表以及状态列表 并且数据量可能很大 先返回操作后下发
    if (CLAN_REQ_CREATE_CLAN == stReq.oper_type() || CLAN_LEARN_SKILL == stReq.oper_type())
    {
        pstMainCtrl->m_stActMgr.NotifyActListToSelf(uiGID);
        pstMainCtrl->m_stStatusMgr.NotifyUserStatusToSelfByGID(uiGID);
        pstMainCtrl->FlushSendCache();
    }
    else if (0 != (unsigned int)stReq.oper_gid() &&
        (CLAN_JOIN_REQ_ACCEPT == stReq.oper_type() ||
        CLAN_FORCE_QUIT_CLAN == stReq.oper_type()))
    {
        pstMainCtrl->m_stActMgr.NotifyActListToSelf((unsigned int)stReq.oper_gid());
        pstMainCtrl->m_stStatusMgr.NotifyUserStatusToSelfByGID((unsigned int)stReq.oper_gid());
        pstMainCtrl->FlushSendCache();
    }
    else if (CLAN_UPGRADE_CLAN == stReq.oper_type())//家族升级
    {
        pstMainCtrl->m_stMagicDoorMgr.NotifyActInfoToAllClanMembers(uiClanId);//比如升级使神树开放
        pstMainCtrl->FlushSendCache();

        pstMainCtrl->m_stStatusMgr.NotifyUserStatusToClanMember(uiClanId);
        pstMainCtrl->FlushSendCache();
    }

    return Done(iRet);
}

void CCmdClanOper::GetClanInfo ()
{
    int iIndex = pstMainCtrl->m_stPlayerDetailInfoHash.HashFind(uiGID);
    if (iIndex < 0)
    {
        return ;
    }
    CPlayerDetailInfo & stPlayerDetailInfo = pstMainCtrl->m_stPlayerDetailInfoHash[iIndex];

    uiClanId = stPlayerDetailInfo._stUserClan._uiClanId;
    CClanEntry stClanEntry;
    pstMainCtrl->m_stClanMgr.GetClanEntry(uiClanId, stClanEntry);
    pstMainCtrl->m_stClanMgr.GetClanBaseInfo (stClanEntry, stPlayerDetailInfo._stUserClan,(*(stAns.mutable_clan_base_info())));
    pstMainCtrl->m_stClanMgr.GetClanDetailInfo (uiClanId, (*(stAns.mutable_clan_detail_info())));

    return ;
}
void CCmdClanOper::SendInfoToFront(SEND_INFO_TYPE enSendType, unsigned int uiGid)
{
    int iIndex = pstMainCtrl->m_stClanMgr._stClanEntryHash.HashFind(uiClanId);
    if (iIndex < 0)
    {
        CT_ERROR(("%d, %d, %d", uiClanId, uiGid, stReq.oper_type()));
        return ;
    }

    PBMsgHead stMsgHeader;
    stMsgHeader.set_msgret(0);
    stMsgHeader.set_msgtype(CSMsgDef::EMT_ANSWER);
    pstMainCtrl->m_stEncodeBuf.Clear();
    CClanEntry & stClanEntry = pstMainCtrl->m_stClanMgr._stClanEntryHash[iIndex];
    switch (enSendType)
    {
    case SEND_CLAN_MEMBER:
        {
            MsgAnsUserClanInfo  stAnsUserClan;
            MsgClanDetailInfo * pstDetailInfo = stAnsUserClan.mutable_clan_detail_info();
            stAnsUserClan.set_oper_type(CLAN_INFO_MEMBER);
            stMsgHeader.set_msgid(ID_MAIN_USER_CLAN_INFO);
            pstMainCtrl->m_stClanMgr.GetClanDetailInfo (stClanEntry._uiClanId, (*pstDetailInfo));
            pstMainCtrl->EncodePBMsg(stMsgHeader, pstMainCtrl->m_stEncodeBuf);
            pstMainCtrl->EncodePBMsg(stAnsUserClan, pstMainCtrl->m_stEncodeBuf);
            for (int i = 0; i < stClanEntry._astClanMember.Size(); i++)
            {
                if (uiGid != stClanEntry._astClanMember[i]._uiGid)
                {
                    pstMainCtrl->NotifyOnlineUser(stClanEntry._astClanMember[i]._uiGid, pstMainCtrl->m_stEncodeBuf);
                }
            }

            return ;
        }
        break;

    case SEND_JOIN_REQ:
        {
            int iGidIndex = pstMainCtrl->m_stPlayerDetailInfoHash.HashFind(uiGid);
            if (iGidIndex < 0)
            {
                break;
            }
            CUserClan & stUserClan = pstMainCtrl->m_stPlayerDetailInfoHash[iGidIndex]._stUserClan;

            stMsgHeader.set_msgid(ID_MAIN_CLAN_OPER);
            MsgAnsClanOper stAns;
            if (stUserClan._uiClanId == uiClanId)
            {
                stAns.set_oper_type(CLAN_JOIN_REQ_ACCEPT);
            }
            else
            {
                stAns.set_oper_type(CLAN_JOIN_REQ_REJECT);
            }

            stAns.set_para1(uiClanId);
            pstMainCtrl->m_stEncodeBuf.Clear();
            pstMainCtrl->EncodePBMsg(stMsgHeader, pstMainCtrl->m_stEncodeBuf);
            pstMainCtrl->EncodePBMsg(stAns, pstMainCtrl->m_stEncodeBuf);
            pstMainCtrl->NotifyOnlineUser(uiGid, pstMainCtrl->m_stEncodeBuf);
        }
        break;

    case SEND_CLAN_PENDING:
        {
            MsgAnsUserClanInfo  stAnsUserClan;
            stAnsUserClan.set_oper_type(CLAN_INFO_PENDING);
            for (int i = 0; i < stClanEntry._astJoinReq.Size(); i++)
            {
                int iGidIndex = pstMainCtrl->m_stPlayerSnsCommInfoHash.HashFind(stClanEntry._astJoinReq[i]);
                if (iGidIndex < 0)
                {
                    continue;
                }

                MsgClanJoinReq * pstJoinReq = stAnsUserClan.add_join_reqs();
                pstJoinReq->set_gid(stClanEntry._astJoinReq[i]);
                pstJoinReq->set_name(pstMainCtrl->m_stPlayerSnsCommInfoHash[iGidIndex]._sRoleName());
                pstJoinReq->set_level(pstMainCtrl->m_stPlayerSnsCommInfoHash[iGidIndex]._usLevel);
                pstJoinReq->set_arena_rank(pstMainCtrl->m_stPlayerSnsCommInfoHash[iGidIndex]._iArenaRank);
            }

            stMsgHeader.set_msgid(ID_MAIN_USER_CLAN_INFO);

            unsigned int uiLeadId = 0;
            unsigned int uiVice1 = 0;
            unsigned int uiVice2 = 0;
            pstMainCtrl->m_stClanMgr.GetClanLeader(uiClanId, uiLeadId);
            stClanEntry.GetClanVice (uiVice1, uiVice2);

            pstMainCtrl->EncodePBMsg(stMsgHeader, pstMainCtrl->m_stEncodeBuf);
            pstMainCtrl->EncodePBMsg(stAnsUserClan, pstMainCtrl->m_stEncodeBuf);
            pstMainCtrl->NotifyOnlineUser(uiLeadId, pstMainCtrl->m_stEncodeBuf);

            if (uiVice1 != 0)
            {
                pstMainCtrl->NotifyOnlineUser(uiVice1, pstMainCtrl->m_stEncodeBuf);
            }
            if (uiVice2 != 0)
            {
                pstMainCtrl->NotifyOnlineUser(uiVice2, pstMainCtrl->m_stEncodeBuf);
            }
        }
        break;
    case SEND_CLAN_INFO:
        {
            MsgAnsUserClanInfo  stAnsUserClan;
            MsgClanBaseInfo * pstBaseInfo = stAnsUserClan.mutable_clan_base_info();
            stAnsUserClan.set_oper_type(CLAN_INFO_BASE);
            stMsgHeader.set_msgid(ID_MAIN_USER_CLAN_INFO);
            CUserClan stUserClan;
            stUserClan._uiClanId = uiClanId;
            pstMainCtrl->m_stClanMgr.GetClanBaseInfo(stClanEntry, stUserClan, (*pstBaseInfo));
            pstMainCtrl->EncodePBMsg(stMsgHeader, pstMainCtrl->m_stEncodeBuf);
            pstMainCtrl->EncodePBMsg(stAnsUserClan, pstMainCtrl->m_stEncodeBuf);
            for (int i = 0; i < stClanEntry._astClanMember.Size(); i++)
            {
                pstMainCtrl->NotifyOnlineUser(stClanEntry._astClanMember[i]._uiGid, pstMainCtrl->m_stEncodeBuf);
            }

            return ;
        }
        break;
    default:
        return ;
    }

    return ;
}

int CCmdClanOper::CallBack(int iRet)
{
    if (m_pstChild->GetCmdID() == ID_MAIN_INNER_CLAN_BONUS)
    {
        CCmdClanBonus* pstChildCmd = (CCmdClanBonus*)m_pstChild;

        UpdateClanData(uiClanId, CLAN_ALLOT_BONUS);
        stAns.CopyFrom(pstChildCmd->_stAns);
        return AnsClients (iRet);
    }

    return RET_OK;
}

CT_REGISTER_ASYNCCMD(ID_MAIN_INNER_CLAN_BONUS, CCmdClanBonus);
int CCmdClanBonus::Do(void* pData)
{
    for (int i = 0; i < _stReq.clan_members_size(); i++)
    {
        _stMembers.AddOneItem(_stReq.clan_members(i));
    }

    StorageItemData stItem;
    for (int i = 0; i < _stReq.items_size(); i++)
    {
        MsgGridItemInfo * pstItem = _stReq.mutable_items(i);
        stItem._ucItemType = pstItem->item_type();
        stItem._uiItemID = pstItem->item_config_id();
        stItem._shItemCount = pstItem->item_count();
        _stBonus.AddOneItem(stItem);
    }

    LogicDo(RET_OK);

    return RET_OK;
}

int CCmdClanBonus::LogicDo(int iRet)
{
    pstMainCtrl = CMainCtrl::m_pstMain;

    if (_stMembers.Size() == 0)
    {
        return Done(iRet);
    }

    if (iRet)
    {
        int iLastMemberIndex = _stMembers.m_iUsedCount - 1;
        unsigned int uiGID = _stMembers[iLastMemberIndex];
        MsgClanMemberInfo * pstFailed = _stAns.add_failed_list();
        pstFailed->set_gid(uiGID);
        CT_ERROR(("%d, %d", uiGID, iRet));
        _stMembers.DelOneItem(iLastMemberIndex);
    }

    while  (_stMembers.Size() > 0)
    {
        int iLastMemberIndex = _stMembers.m_iUsedCount - 1;
        unsigned int uiGID = _stMembers[iLastMemberIndex];

        PREPARE_PLAYER_BASE_INFO(this, uiGID);
        PREPARE_PLAYER_DETAIL_INFO(this, uiGID);

        int iBaseIndex = pstMainCtrl->m_stPlayerBaseInfoHash.HashFind(uiGID);
        int iIndex = pstMainCtrl->m_stPlayerDetailInfoHash.HashFind(uiGID);
        int iSnsIndex = pstMainCtrl->m_stPlayerSnsCommInfoHash.HashFind(uiGID);
        if (iIndex < 0 || iSnsIndex < 0 || iBaseIndex < 0)
        {
            MsgClanMemberInfo * pstFailed = _stAns.add_failed_list();
            pstFailed->set_gid(uiGID);

            CT_ERROR(("%d, %d, %d", uiGID, iIndex, iSnsIndex));
            _stMembers.DelOneItem(iLastMemberIndex);
            continue;
        }
        CPlayerBaseInfo& stPlayerBaseInfo = pstMainCtrl->m_stPlayerBaseInfoHash[iBaseIndex];
        CPlayerDetailInfo & stPlayerDetailInfo = pstMainCtrl->m_stPlayerDetailInfoHash[iIndex];
        CPlayerSnsCommInfo & stPlayerSnsInfo = pstMainCtrl->m_stPlayerSnsCommInfoHash[iSnsIndex];

        if (stPlayerDetailInfo._stUserClan._uiClanId != _uiClanId)
        {
            MsgClanMemberInfo * pstFailed = _stAns.add_failed_list();
            pstFailed->set_gid(uiGID);
            pstFailed->set_name(stPlayerSnsInfo._sRoleName());

            CT_ERROR(("%d, %d, %d", uiGID, stPlayerDetailInfo._stUserClan._uiClanId, _uiClanId));
            _stMembers.DelOneItem(iLastMemberIndex);
            continue;
        }

        if (stPlayerDetailInfo._stUserClan.GetFreeGridCnt() < _stReq.items_size())
        {
            MsgClanMemberInfo * pstFailed = _stAns.add_failed_list();
            pstFailed->set_gid(uiGID);
            pstFailed->set_name(stPlayerSnsInfo._sRoleName());

            CT_ERROR(("%d, %d, %d", uiGID, stPlayerDetailInfo._stUserClan.GetFreeGridCnt(), _stReq.items_size()));
            _stMembers.DelOneItem(iLastMemberIndex);
            continue;
        }

        iRet = pstMainCtrl->m_stClanMgr.TakeOutItem(_uiClanId, _stBonus);
        if (iRet)
        {
            MsgClanMemberInfo * pstFailed = _stAns.add_failed_list();
            pstFailed->set_gid(uiGID);
            pstFailed->set_name(stPlayerSnsInfo._sRoleName());
            _stMembers.DelOneItem(iLastMemberIndex);
            continue;
        }

        for (int i = 0; i < _stBonus.Size(); i++)
        {
            stPlayerDetailInfo._stUserClan.AddBonus(_stBonus[i]);
        }

        CVarObjectKey stKey;
        stKey.m_u64ID = uiGID;
        stKey.m_chDataType = DT_PLAYER_DETAIL_INFO;
        pstMainCtrl->UpdateData(stKey, stPlayerDetailInfo, VOP_UPDATE);

        //发送通知
        pstMainCtrl->m_stGiftMgr.CheckNotify(stPlayerBaseInfo, stPlayerDetailInfo);

        //删除掉最后一个已处理的
        _stMembers.DelOneItem(iLastMemberIndex);
    }

    return Done(RET_OK);
}

CT_REGISTER_ASYNCCMD(ID_MAIN_ZONE_CLAN_INFO, CCmdZoneClanInfo);

int CCmdZoneClanInfo::Do(void* pData)
{
    CT_ASSERT(pData);

    //解析消息
    CCmdPBDoParam* pstParam = (CCmdPBDoParam*) pData;
    pstMainCtrl = (CMainCtrl*) pstParam->m_pMain;

    if (pstParam->m_pstMsgHead->msgid() != ID_MAIN_ZONE_CLAN_INFO ||
        pstParam->m_pstMsgHead->msgtype() != CSMsgDef::EMT_REQUEST)
    {
        CT_ERROR(("Cmd Stat Err Cmd=%d CmdID=%d Type=%d",
            ID_MAIN_ZONE_CLAN_INFO,
            pstParam->m_pstMsgHead->msgid(),
            pstParam->m_pstMsgHead->msgtype()));
        return Done(RET_SYS_ERROR);
    }

    stMsgHead = *(pstParam->m_pstMsgHead);
    stEnpHead = *(pstParam->m_pstEnpHead);
    int iRet = pstMainCtrl->DecodePBMsg(stReq, pstParam);
    if (iRet)
    {
        return AnsClients(iRet);
    }
    //消息解析结束

    uiGID = (unsigned int)stReq.gid();

    //检查登录
    iRet = pstMainCtrl->CheckLogin(uiGID, stEnpHead);
    if (iRet != RET_OK)
    {
        return AnsClients(iRet);
    }

    LogicDo(RET_OK);
    return RET_OK;
}

int CCmdZoneClanInfo::LogicDo(int iRet)
{
    if (iRet)
    {
        return AnsClients(iRet);
    }

    PREPARE_PLAYER_BASE_INFO(this, uiGID);
    PREPARE_PLAYER_DETAIL_INFO(this, uiGID);

    int iIndex = pstMainCtrl->m_stPlayerBaseInfoHash.HashFind(uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("get user player base info error, uid = %u", uiGID));
        return AnsClients(RET_SYSTEM_FAIL);
    }
    CPlayerBaseInfo& stPlayerBaseInfo = pstMainCtrl->m_stPlayerBaseInfoHash[iIndex];

    if (stPlayerBaseInfo._ucIsInited != 1)
    {
        return AnsClients(ERROR_NOT_INITED);
    }

    unsigned int uiClanId = (unsigned int)stReq.clan_id();
    int iGidIndex = pstMainCtrl->m_stPlayerDetailInfoHash.HashFind(uiGID);
    if (iGidIndex < 0)
    {
        return AnsClients(RET_SYS_ERROR);
    }
    CUserClan & stUserClan = pstMainCtrl->m_stPlayerDetailInfoHash[iGidIndex]._stUserClan;

    pstMainCtrl->m_stClanMgr.CheckAndSortClan ();

    if (0 != uiClanId)
    {
        iRet = pstMainCtrl->m_stClanMgr.GetClanDetailInfo (uiClanId, (*(stAns.mutable_clan_detail_info())));
    }
    else
    {
        int iTotalPages = 0;
        iRet = pstMainCtrl->m_stClanMgr.GetClanInfo (stReq.page_beg(), stReq.page_end(), stReq.page_cnt(),
            stUserClan, (*(stAns.mutable_clan_base_infos())), iTotalPages);
        stAns.set_page_no(stReq.page_beg());
        stAns.set_total_page_num(iTotalPages);
    }

    return AnsClients(iRet);
}

int CCmdZoneClanInfo::AnsClients(int iRet)
{
    stMsgHead.set_msgret(iRet);
    stMsgHead.set_msgtype(CSMsgDef::EMT_ANSWER);

    if (iRet != RET_OK)
    {
        pstMainCtrl->ReturnMsgHead(stMsgHead, stEnpHead);
        return Done(iRet);
    }

    pstMainCtrl->m_stEncodeBuf.Clear();
    pstMainCtrl->EncodePBMsg(stMsgHead, pstMainCtrl->m_stEncodeBuf);
    pstMainCtrl->EncodePBMsg(stAns, pstMainCtrl->m_stEncodeBuf);
    if (pstMainCtrl->AnswerToClient(stEnpHead, pstMainCtrl->m_stEncodeBuf,true))
    {
        CT_WARNING((""));
        return Done(RET_SYS_ERROR);
    }

    return Done(iRet);
}

CT_REGISTER_ASYNCCMD(ID_MAIN_USER_CLAN_INFO, CCmdUserClanInfo);
int CCmdUserClanInfo::Do(void* pData)
{
    CT_ASSERT(pData);

    //解析消息
    CCmdPBDoParam* pstParam = (CCmdPBDoParam*) pData;
    pstMainCtrl = (CMainCtrl*) pstParam->m_pMain;

    if (pstParam->m_pstMsgHead->msgid() != ID_MAIN_USER_CLAN_INFO ||
        pstParam->m_pstMsgHead->msgtype() != CSMsgDef::EMT_REQUEST)
    {
        CT_ERROR(("Cmd Stat Err Cmd=%d CmdID=%d Type=%d",
            ID_MAIN_USER_CLAN_INFO,
            pstParam->m_pstMsgHead->msgid(),
            pstParam->m_pstMsgHead->msgtype()));
        return Done(RET_SYS_ERROR);
    }

    stMsgHead = *(pstParam->m_pstMsgHead);
    stEnpHead = *(pstParam->m_pstEnpHead);
    int iRet = pstMainCtrl->DecodePBMsg(stReq, pstParam);
    if (iRet)
    {
        return AnsClients(iRet);
    }
    //消息解析结束

    uiGID = (unsigned int)stReq.gid();

    //检查登录
    iRet = pstMainCtrl->CheckLogin(uiGID, stEnpHead);
    if (iRet != RET_OK)
    {
        return AnsClients(iRet);
    }

    LogicDo(RET_OK);
    return RET_OK;
}

int CCmdUserClanInfo::LogicDo(int iRet)
{
    if (iRet)
    {
        return AnsClients(iRet);
    }

    PREPARE_PLAYER_BASE_INFO(this, uiGID);
    PREPARE_PLAYER_DETAIL_INFO(this, uiGID);

    int iIndex = pstMainCtrl->m_stPlayerBaseInfoHash.HashFind(uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("get user player base info error, uid = %u", uiGID));
        return AnsClients(RET_SYSTEM_FAIL);
    }
    CPlayerBaseInfo& stPlayerBaseInfo = pstMainCtrl->m_stPlayerBaseInfoHash[iIndex];

    if (stPlayerBaseInfo._ucIsInited != 1)
    {
        return AnsClients(ERROR_NOT_INITED);
    }

    unsigned char ucInfoType = (unsigned char)(stReq.info_type() & 0x7F);
    iIndex = pstMainCtrl->m_stPlayerDetailInfoHash.HashFind(uiGID);
    if (iIndex < 0)
    {
        return AnsClients(RET_NO_USER);
    }
    CPlayerDetailInfo & stPlayerDetailInfo = pstMainCtrl->m_stPlayerDetailInfoHash[iIndex];

    if (CLAN_INFO_SKILL == ucInfoType)
    {
        iRet = pstMainCtrl->m_stClanMgr.GetClanSkill (stPlayerDetailInfo._stUserClan, stAns);
        return AnsClients(iRet);
    }

    if (0 == stPlayerDetailInfo._stUserClan._uiClanId)
    {
        return AnsClients(ERROR_CLAN_NOT_EXIST);
    }

    pstMainCtrl->m_stClanMgr.CheckAndSortClan ();

    //检查用户的家族是否合法
    bool bNeedClearClan = false;
    int iClanIndex = pstMainCtrl->m_stClanMgr.GetClanIndexByClanId(stPlayerDetailInfo._stUserClan._uiClanId);
    if (iClanIndex < 0)
    {
        bNeedClearClan = true;
    }
    else
    {
        //处理2013-07-30号的家族BUG, 家族族长不存在时的特殊处理
        unsigned int uiLeadGid = 0;
        iRet = pstMainCtrl->m_stClanMgr.GetClanLeader(stPlayerDetailInfo._stUserClan._uiClanId, uiLeadGid);
        if (RET_OK != iRet)
        {
            bNeedClearClan = true;
        }
    }

    if (bNeedClearClan)
    {
        //家族被解散了. 清空sns和detail中数据
        PREPARE_PLAYER_SNS_DETAIL_INFO(this, uiGID);

        stPlayerDetailInfo._stUserClan.ClearWhenNoClan();
        pstMainCtrl->m_stClanMgr.SetSnsClanId (uiGID, 0);
        pstMainCtrl->m_stNotifyMgr.Notify(uiGID, NOTIFY_ROLE_INFO);

        return AnsClients(ERROR_CLAN_NOT_EXIST);
    }

    CClanEntry & stClanEntry = pstMainCtrl->m_stClanMgr.GetClanEntry(iClanIndex);
    switch (ucInfoType)
    {
    case CLAN_INFO_MEMBER:
        {
            MsgClanBaseInfo * pstBaseInfo = stAns.mutable_clan_base_info();
            iRet = pstMainCtrl->m_stClanMgr.GetClanBaseInfo (stClanEntry, stPlayerDetailInfo._stUserClan, *pstBaseInfo);
            if (iRet)
            {
                return AnsClients(iRet);
            }

            iRet = pstMainCtrl->m_stClanMgr.GetClanDetailInfo (stClanEntry._uiClanId, (*(stAns.mutable_clan_detail_info())));
        }
        break;

    case CLAN_INFO_MEMBERLOG:
        {
            iRet = pstMainCtrl->m_stClanMgr.GetClanLog (stClanEntry._uiClanId, 2, stAns);
        }
        break;

    case CLAN_INFO_ACTIVITY:
        {
        }
        break;

    case CLAN_INFO_PENDING:    //待审核的申请加入列表
        {
            for (int i = 0; i < stClanEntry._astJoinReq.Size(); i++)
            {
                MsgClanJoinReq * pstJoinReq = stAns.add_join_reqs();

                int iGidIndex = pstMainCtrl->m_stPlayerSnsCommInfoHash.HashFind(stClanEntry._astJoinReq[i]);
                if (iGidIndex < 0)
                {
                    return AnsClients(RET_SYS_ERROR);
                }

                pstJoinReq->set_gid(stClanEntry._astJoinReq[i]);
                pstJoinReq->set_name(pstMainCtrl->m_stPlayerSnsCommInfoHash[iGidIndex]._sRoleName());
                pstJoinReq->set_level(pstMainCtrl->m_stPlayerSnsCommInfoHash[iGidIndex]._usLevel);
                pstJoinReq->set_arena_rank(pstMainCtrl->m_stPlayerSnsCommInfoHash[iGidIndex]._iArenaRank);
                pstJoinReq->set_is_male(pstMainCtrl->m_stPlayerSnsCommInfoHash[iGidIndex]._ucIsMale);
            }
        }
        break;

    case CLAN_INFO_BASE:
        {
            MsgClanBaseInfo * pstBaseInfo = stAns.mutable_clan_base_info();
            iRet = pstMainCtrl->m_stClanMgr.GetClanBaseInfo (stClanEntry, stPlayerDetailInfo._stUserClan, *pstBaseInfo);
            if (iRet)
            {
                return AnsClients(iRet);
            }
        }
        break;

    case CLAN_INFO_CLANLOG:
        {
            iRet = pstMainCtrl->m_stClanMgr.GetClanLog (stClanEntry._uiClanId, 7, stAns);
        }
        break;

    case CLAN_INFO_STORAGE:    //家族仓库
        {
            pstMainCtrl->m_stStorageMgr.GetStorageInfo(STORAGE_TYPE_CLAN, uiGID, stClanEntry._stStorage, *(stAns.mutable_clan_bag()));
        }
        break;

    default:
        return AnsClients(ERROR_CLAN_PARA_INVALID);
    }

    return AnsClients(iRet);
}

int CCmdUserClanInfo::AnsClients(int iRet)
{
    stMsgHead.set_msgret(iRet);
    stMsgHead.set_msgtype(CSMsgDef::EMT_ANSWER);

    if (iRet != RET_OK)
    {
        pstMainCtrl->ReturnMsgHead(stMsgHead, stEnpHead);
        return Done(iRet);
    }

    stAns.set_oper_type(stReq.info_type());
    pstMainCtrl->m_stEncodeBuf.Clear();
    pstMainCtrl->EncodePBMsg(stMsgHead, pstMainCtrl->m_stEncodeBuf);
    pstMainCtrl->EncodePBMsg(stAns, pstMainCtrl->m_stEncodeBuf);
    if (pstMainCtrl->AnswerToClient(stEnpHead, pstMainCtrl->m_stEncodeBuf,true))
    {
        CT_WARNING((""));
        return Done(RET_SYS_ERROR);
    }

    return Done(iRet);
}

//////////////////////////////////////////////////////////////////////////
CT_REGISTER_ASYNCCMD(ID_MAIN_CLAN_BATTLE , CCmdClanBattle);

int CCmdClanBattle::Do(void* pData)
{
    CT_ASSERT(pData);
    int iRet = 0;

    //解析消息
    CCmdPBDoParam* pstParam = (CCmdPBDoParam*) pData;
    pstMainCtrl = (CMainCtrl*) pstParam->m_pMain;

    if (pstParam->m_pstMsgHead->msgid() != ID_MAIN_CLAN_BATTLE ||
        pstParam->m_pstMsgHead->msgtype() != CSMsgDef::EMT_REQUEST)
    {
        CT_ERROR(("Cmd Stat Err Cmd=%d CmdID=%d Type=%d",
            ID_MAIN_CLAN_BATTLE,
            pstParam->m_pstMsgHead->msgid(),
            pstParam->m_pstMsgHead->msgtype()));
        return Done(RET_SYS_ERROR);
    }

    stMsgHead = *(pstParam->m_pstMsgHead);
    stEnpHead = *(pstParam->m_pstEnpHead);
    iRet = pstMainCtrl->DecodePBMsg(stReq, pstParam);
    if (iRet)
    {
        return AnsClients(iRet);
    }
    //消息解析结束

    uiGID = (unsigned int)stReq.gid();

    //检查登录
    iRet = pstMainCtrl->CheckLogin(uiGID, stEnpHead);
    if (iRet != RET_OK)
    {
        return AnsClients(iRet);
    }

    LogicDo(RET_OK);
    return iRet;
}

int CCmdClanBattle::LogicDo(int iRet)
{
    if (iRet)
    {
        return AnsClients(iRet);
    }

    PREPARE_PLAYER_BASE_INFO(this, uiGID);
    ASSERT_PLAYER_PREPARED(uiGID);

    PREPARE_PLAYER_DETAIL_INFO(this, uiGID);
    ASSERT_PLAYER_DETAIL_PREPARED(uiGID);

    PREPARE_PLAYER_ONLINE_DATA(this, uiGID);

    int iIndex = pstMainCtrl->m_stPlayerBaseInfoHash.HashFind(uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("online user %u has no base info", uiGID));
        return AnsClients(RET_SYSTEM_FAIL);
    }
    CPlayerBaseInfo& stPlayerBaseInfo = pstMainCtrl->m_stPlayerBaseInfoHash[iIndex];

    if (stPlayerBaseInfo._ucIsInited != 1)
    {
        return AnsClients(ERROR_NOT_INITED);
    }

    iIndex = pstMainCtrl->m_stPlayerDetailInfoHash.HashFind(uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("online user %u has no base info", uiGID));
        return AnsClients(RET_SYSTEM_FAIL);
    }
    CPlayerDetailInfo& stPlayerDetailInfo = pstMainCtrl->m_stPlayerDetailInfoHash[iIndex];

    iIndex = pstMainCtrl->m_stPlayerOnlineDataHash.HashFind(uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("online user %u has no online data", uiGID));
        return AnsClients(RET_SYSTEM_FAIL);
    }
    CPlayerOnlineData& stPlayerOnlineData = pstMainCtrl->m_stPlayerOnlineDataHash[iIndex];

    unsigned char ucOpt = stReq.opt();
    stAns.set_opt(stReq.opt());

    switch (ucOpt)
    {
    case 1: //报名
        {
            iRet = pstMainCtrl->m_stClanBattleMgr.AddRole(stPlayerBaseInfo, stPlayerDetailInfo, stPlayerOnlineData);

            if (RET_OK == iRet)
            {
                //触发任务
                CMainCtrl::m_pstMain->m_stDailyTaskMgr.TriggerTaskFinish(stPlayerOnlineData._stUserDailyTask, DAILY_TASK_ID_20);
            }
        }
        break;
    case 2: //获取战斗录像
        {
            /*
            if (!pstMainCtrl->m_stClanBattleMgr.IsBegin())
            {
            return AnsClients(ERROR_CLAN_BATTLE_NOT_BEGIN);
            }
            */

            if (pstMainCtrl->m_stClanBattleMgr.IsInProgress())
            {
                stAns.set_is_in_progress(1);
                stAns.set_next_can_get_info_time(pstMainCtrl->m_iNow + 2);
                return AnsClients(RET_OK);
            }

            iRet = pstMainCtrl->m_stClanBattleMgr.GetVideo(stPlayerDetailInfo._stUserClan._uiClanId, (*stAns.mutable_videos()));
            stAns.set_next_can_get_info_time(pstMainCtrl->m_stClanBattleMgr.GetNextRoundBeginTime() + 30);
        }
        break;
    case 3: //获取排行信息
        {
            if (pstMainCtrl->m_stClanBattleMgr.IsInProgress())
            {
                stAns.set_is_in_progress(1);
                stAns.set_next_can_get_info_time(pstMainCtrl->m_iNow + 2);
                return AnsClients(RET_OK);
            }

            pstMainCtrl->m_stClanBattleMgr.GetClanRank((*stAns.mutable_clan_rank()));
            pstMainCtrl->m_stClanBattleMgr.GetRoleRank((*stAns.mutable_role_rank()));
        }
        break;
    case 4: //鼓舞
        {
            if (!pstMainCtrl->m_stClanBattleMgr.IsBegin())
            {
                return AnsClients(ERROR_CLAN_BATTLE_NOT_BEGIN);
            }

            unsigned int uiDestGID = stReq.dest_gid();

            iIndex = pstMainCtrl->FindPlayerCacheData(uiDestGID);
            if (iIndex < 0)
            {
                CT_ERROR((""));
                return AnsClients(RET_SYS_ERROR);
            }
            CPlayerCacheData& stPlayerCacheData = pstMainCtrl->m_stPlayerCacheDataHash[iIndex];

            int iNowInspireCount = 0;
            iRet = pstMainCtrl->m_stClanBattleMgr.Inspire(uiGID, stReq.dest_gid(), iNowInspireCount);
            if (RET_OK == iRet)
            {
                //给身上加能力，显示用
                pstMainCtrl->m_stStatusMgr.AddStatus(stPlayerCacheData, CStatusUnit::STATUS_ID_CLAN_BATTLE_INSPIRE,
                    pstMainCtrl->m_iNow + 3600 * 2, 0, true);//因为状态清除包括到期时间或者活动关闭 这里活动ID填0 避免清除

                stAns.set_inspire_gid(uiDestGID);
                stAns.set_now_inspire_count(iNowInspireCount);
            }
        }
    case 5:  //获取家族战个人信息
        {
            stAns.set_has_start(pstMainCtrl->m_stClanBattleMgr.IsBegin() ? 1 : 0);
            stAns.set_has_enter(pstMainCtrl->m_stClanBattleMgr.HasEnter(uiGID) ? 1 : 0);
            stAns.set_act_begin_time(pstMainCtrl->m_stClanBattleMgr.GetBeginTime());
            stAns.set_can_enter(pstMainCtrl->m_stClanBattleMgr.IsCanAddRole() ? 1 : 0);

            if (pstMainCtrl->m_stClanBattleMgr.IsBegin()) //提供战斗记录
            {
                pstMainCtrl->m_stClanBattleMgr.GetBattleRecorder(uiGID, *stAns.mutable_battle_recorders());
            }
        }
        break;
    case 6: //获取家族战家族信息
        {
            stAns.set_is_can_inspire(pstMainCtrl->m_stClanBattleMgr.IsCanInspire(uiGID) ? 1 : 0);
            iRet = pstMainCtrl->m_stClanBattleMgr.GetClanRole(stPlayerDetailInfo._stUserClan._uiClanId, *(stAns.mutable_clan_role()));
        }
        break;
    default:
        return AnsClients(RET_SYS_ERROR);
    }

    return AnsClients(iRet);
}

int CCmdClanBattle::AnsClients(int iRet)
{
    stMsgHead.set_msgret(iRet);
    stMsgHead.set_msgtype(CSMsgDef::EMT_ANSWER);

    pstMainCtrl->m_stEncodeBuf.Clear();
    pstMainCtrl->EncodePBMsg(stMsgHead, pstMainCtrl->m_stEncodeBuf);
    pstMainCtrl->EncodePBMsg(stAns, pstMainCtrl->m_stEncodeBuf);
    if (pstMainCtrl->AnswerToClient(stEnpHead, pstMainCtrl->m_stEncodeBuf,true))
    {
        CT_WARNING((""));
        return Done(RET_SYS_ERROR);
    }

    return Done(iRet);
}

//////////////////////////////////////////////////////////////////////////
CT_REGISTER_ASYNCCMD(ID_MAIN_CLAN_TREE , CCmdClanTree);

int CCmdClanTree::Do(void* pData)
{
    CCmdPBDoParam* pstParam = (CCmdPBDoParam*) pData;
    pstMainCtrl = (CMainCtrl*) pstParam->m_pMain;

    if (pstParam->m_pstMsgHead->msgid() != ID_MAIN_CLAN_TREE ||
        pstParam->m_pstMsgHead->msgtype() != CSMsgDef::EMT_REQUEST)
    {
        CT_ERROR(("Cmd Stat Err Cmd=%d CmdID=%d Tpye=%d", ID_MAIN_CLAN_TREE,
            pstParam->m_pstMsgHead->msgid(),
            pstParam->m_pstMsgHead->msgtype()));
        return Done(RET_SYS_ERROR);
    }

    stMsgHead = *(pstParam->m_pstMsgHead);
    stEnpHead = *(pstParam->m_pstEnpHead);
    int iRet = pstMainCtrl->DecodePBMsg(stReq, pstParam);
    if (iRet)
    {
        return AnsClients(iRet);
    }

    //检查登录
    iRet = pstMainCtrl->CheckLogin(stReq.gid(), stEnpHead);
    if (iRet != RET_OK)
    {
        return AnsClients(iRet);
    }

    _uiGID = stReq.gid();
    LogicDo(RET_OK);
    return RET_OK;
}

int CCmdClanTree::LogicDo(int iRet)
{
    if (iRet)
    {
        return AnsClients(iRet);
    }

    int iOpt = stReq.opt();

    PREPARE_PLAYER_BASE_INFO(this, _uiGID);
    PREPARE_PLAYER_DETAIL_INFO(this, _uiGID);
    PREPARE_PLAYER_ONLINE_DATA(this, _uiGID);

    int iIndex = 0;
    iIndex = pstMainCtrl->m_stPlayerBaseInfoHash.HashFind(_uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("gid = %u", _uiGID));
        return AnsClients(RET_SYS_ERROR);
    }
    CPlayerBaseInfo& stPlayerBaseInfo = pstMainCtrl->m_stPlayerBaseInfoHash[iIndex];

    if (stPlayerBaseInfo._ucIsInited != 1)
    {
        return AnsClients(ERROR_NOT_INITED);
    }

    iIndex = pstMainCtrl->m_stPlayerDetailInfoHash.HashFind(_uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("gid = %u", _uiGID));
        return AnsClients(RET_SYS_ERROR);
    }
    CPlayerDetailInfo& stPlayerDetailInfo = pstMainCtrl->m_stPlayerDetailInfoHash[iIndex];

    iIndex = pstMainCtrl->m_stPlayerOnlineDataHash.HashFind(_uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("gid = %u", _uiGID));
        return AnsClients(RET_SYS_ERROR);
    }
    CPlayerOnlineData& stPlayerOnlineData = pstMainCtrl->m_stPlayerOnlineDataHash[iIndex];

    int iClanIndex = pstMainCtrl->m_stClanMgr.GetClanIndex(_uiGID);
    if (iClanIndex < 0)
    {
        return AnsClients(ERROR_CLAN_NOT_EXIST);
    }

    CClanEntry & stClanEntry = pstMainCtrl->m_stClanMgr._stClanEntryHash[iClanIndex];
    CTreeData & stTreeData = stClanEntry._stTree;
    CUserTree & stUserTree = stPlayerDetailInfo._stUserClan._stTreeData;
    unsigned char ucTreeId = (unsigned char)stReq.tree();

    if ((0 != iOpt) &&
        (false == pstMainCtrl->m_stTreeMgr.IsTreeUnLock(ucTreeId, stClanEntry._ucClanLevel)))
    {
        return AnsClients(ERROR_CLAN_TREE_LOCKED);
    }

    switch (iOpt)
    {
    case 0:
        iRet = RET_OK;
        break;

    case 1:
        {
            iRet = pstMainCtrl->m_stTreeMgr.WaterTree(stPlayerBaseInfo, ucTreeId, stClanEntry, stUserTree, stAns);
            if (RET_OK == iRet)
            {
                pstMainCtrl->m_stClanMgr.UpdateToDB(stClanEntry._uiClanId);

                //触发任务
                pstMainCtrl->m_stTaskMgr.TriggerDoSomeOpt(stPlayerOnlineData._stUserTask, TASK_OPT_ID_127, 1);

                if (!pstMainCtrl->m_stTreeMgr.CanDoTreeOpt(stPlayerBaseInfo, stPlayerDetailInfo._stUserClan))
                {
                    pstMainCtrl->m_stActMgr.NotifyActListToSelf(stPlayerBaseInfo._uiGID);
                }
            }
        }
        break;

    case 2:
        {
            iRet = pstMainCtrl->m_stTreeMgr.PickFruit(_uiGID, stReq.data(), ucTreeId, stTreeData, stUserTree, stAns);
            if (RET_OK == iRet)
            {
                if (!pstMainCtrl->m_stTreeMgr.CanDoTreeOpt(stPlayerBaseInfo, stPlayerDetailInfo._stUserClan))
                {
                    pstMainCtrl->m_stActMgr.NotifyActListToSelf(stPlayerBaseInfo._uiGID);
                }
            }
        }
        break;

    default:
        iRet = ERROR_CLAN_TREE_OPT;
    }

    if (iRet)
    {
        return AnsClients(iRet);
    }

    CVarObjectKey stKey;
    stKey.m_chDataType = DT_PLAYER_DETAIL_INFO;
    stKey.m_u64ID = _uiGID;
    CMainCtrl::m_pstMain->UpdateData(stKey, stPlayerDetailInfo, VOP_UPDATE);

    pstMainCtrl->m_stTreeMgr.GetTreeInfo(stPlayerBaseInfo, stClanEntry, ucTreeId, stUserTree, stAns);
    return AnsClients(iRet);
}

int CCmdClanTree::AnsClients(int iRet)
{
    stMsgHead.set_msgret(iRet);
    stMsgHead.set_msgtype(CSMsgDef::EMT_ANSWER);
    if (iRet != RET_OK)
    {
        pstMainCtrl->ReturnMsgHead(stMsgHead, stEnpHead);
        return Done(iRet);
    }

    stAns.set_opt(stReq.opt());
    pstMainCtrl->m_stEncodeBuf.Clear();
    pstMainCtrl->EncodePBMsg(stMsgHead, pstMainCtrl->m_stEncodeBuf);
    pstMainCtrl->EncodePBMsg(stAns, pstMainCtrl->m_stEncodeBuf);
    if (pstMainCtrl->AnswerToClient(stEnpHead, pstMainCtrl->m_stEncodeBuf,true))
    {
        CT_WARNING((""));
        return Done(RET_SYS_ERROR);
    }

    return Done(iRet);
}

//////////////////////////////////////////////////////////////////////////
CT_REGISTER_ASYNCCMD(ID_MAIN_CLAN_DIAL , CCmdClanDial);

int CCmdClanDial::Do(void* pData)
{
    CCmdPBDoParam* pstParam = (CCmdPBDoParam*) pData;
    pstMainCtrl = (CMainCtrl*) pstParam->m_pMain;

    if (pstParam->m_pstMsgHead->msgid() != ID_MAIN_CLAN_DIAL ||
        pstParam->m_pstMsgHead->msgtype() != CSMsgDef::EMT_REQUEST)
    {
        CT_ERROR(("Cmd Stat Err Cmd=%d CmdID=%d Tpye=%d", ID_MAIN_CLAN_DIAL,
            pstParam->m_pstMsgHead->msgid(),
            pstParam->m_pstMsgHead->msgtype()));
        return Done(RET_SYS_ERROR);
    }

    stMsgHead = *(pstParam->m_pstMsgHead);
    stEnpHead = *(pstParam->m_pstEnpHead);
    int iRet = pstMainCtrl->DecodePBMsg(stReq, pstParam);
    if (iRet)
    {
        return AnsClients(iRet);
    }

    //检查登录
    iRet = pstMainCtrl->CheckLogin(stReq.gid(), stEnpHead);
    if (iRet != RET_OK)
    {
        return AnsClients(iRet);
    }

    _uiGID = stReq.gid();
    LogicDo(RET_OK);
    return RET_OK;
}

int CCmdClanDial::LogicDo(int iRet)
{
    if (iRet)
    {
        return AnsClients(iRet);
    }

    PREPARE_PLAYER_BASE_INFO(this, _uiGID);
    PREPARE_PLAYER_DETAIL_INFO(this, _uiGID);
    PREPARE_PLAYER_SNS_DETAIL_INFO(this, _uiGID);

    int iIndex = 0;
    iIndex = pstMainCtrl->m_stPlayerBaseInfoHash.HashFind(_uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("gid = %u", _uiGID));
        return AnsClients(RET_SYS_ERROR);
    }
    CPlayerBaseInfo& stPlayerBaseInfo = pstMainCtrl->m_stPlayerBaseInfoHash[iIndex];

    if (stPlayerBaseInfo._ucIsInited != 1)
    {
        return AnsClients(ERROR_NOT_INITED);
    }

    iIndex = pstMainCtrl->m_stPlayerDetailInfoHash.HashFind(_uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("gid = %u", _uiGID));
        return AnsClients(RET_SYS_ERROR);
    }
    CPlayerDetailInfo& stPlayerDetailInfo = pstMainCtrl->m_stPlayerDetailInfoHash[iIndex];

    iIndex = pstMainCtrl->m_stPlayerSnsDetailInfoHash.HashFind(_uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("%d", _uiGID));
        return AnsClients(RET_NO_USER);
    }
    CPlayerSnsDetailInfo & stPlayerSnsDetailInfo = pstMainCtrl->m_stPlayerSnsDetailInfoHash[iIndex];

    int iClanIndex = pstMainCtrl->m_stClanMgr.GetClanIndex(_uiGID);
    if (iClanIndex < 0)
    {
        return AnsClients(ERROR_CLAN_NOT_EXIST);
    }

    bool bNeedSaveDetail = false;

    int iOpt = stReq.opt();
    int iMaxDailCnt = 0;
    switch (iOpt)
    {
    case 1:
        {
            CGiftConfigUnit stCfg;
            iRet = pstMainCtrl->m_stItemMgr.GetGiftConfig (CLAN_DAIL_GIFT_ID, stCfg);
            if (iRet)
            {
                CT_ERROR(("%d, %d", CLAN_DAIL_GIFT_ID, iRet));
                return AnsClients(iRet);
            }

            for (int i = 0; i < stCfg._astToDropItems.Size(); i++)
            {
                CGiftItem & stGiftItem = stCfg._astToDropItems[i]._stItem;
                MsgGridItemInfo * pstGrid = stAns.add_items_in_dail();
                pstGrid->set_item_type(stGiftItem._ucItemType);
                pstGrid->set_item_config_id(stGiftItem._usItemId);
                pstGrid->set_item_count(stGiftItem._uiItemCount);
            }
        }
        break;

    case 3:
        {
            PREPARE_PLAYER_ONLINE_DATA(this, _uiGID);

            iIndex = pstMainCtrl->m_stPlayerOnlineDataHash.HashFind(_uiGID);
            if (iIndex < 0)
            {
                CT_ERROR(("gid = %u", _uiGID));
                return AnsClients(RET_NO_USER);
            }
            CPlayerOnlineData& stPlayerOnlineData = pstMainCtrl->m_stPlayerOnlineDataHash[iIndex];

            if (stPlayerSnsDetailInfo._stCommInfo._iContribution < CLAN_DAIL_NEED_CONTRI)
            {
                return AnsClients(ERROR_LACK_DAIL_CONT);
            }

            if (stPlayerOnlineData._stUserStorage.BagIsFull())
            {
                return AnsClients(ERROR_STORAGE_BAG_IS_FULL);
            }

            int iLeftDailCount = pstMainCtrl->m_stClanMgr.GetLeftDailCount(stPlayerBaseInfo._chVipLevel, stPlayerDetailInfo, pstMainCtrl->m_iNow, iMaxDailCnt);
            if (iLeftDailCount <= 0)
            {
                return AnsClients(ERROR_LACK_DIAL_CNT);
            }

            CDropItem stDialItem;
            iRet = pstMainCtrl->m_stItemMgr.GetGiftItem(CLAN_DAIL_GIFT_ID, _uiGID, stDialItem, false);
            if (iRet)
            {
                CT_ERROR(("%d, %d", CLAN_DAIL_GIFT_ID, iRet));
                return AnsClients(iRet);
            }

            if (stDialItem.Size() != 1)
            {
                CT_ERROR(("%d, %d, %d",  _uiGID, stDialItem.Size(), iLeftDailCount));
                return AnsClients(ERROR_GIFT_DROP_WRONG);
            }

            CT_TRACE(("%d, %d, %d, %d, %d", _uiGID, iLeftDailCount, stDialItem._astDropItem[0]._ucItemType, stDialItem._astDropItem[0]._usItemConfigID, stDialItem._astDropItem[0]._iData1));
            stAns.set_item_pos(stDialItem._astDropItem[0]._iData1);

            //iData1参数的意义被重新定义了, 很容易出错
            stDialItem._astDropItem[0]._iData1 = ADD_GIFT_BAG;

            //修改用户数据
            bNeedSaveDetail = true;
            stPlayerDetailInfo._stUserClan._stDailCnt.Add(1, pstMainCtrl->m_iNow, CLAN_DAIL_RESET_TIME);
            stPlayerSnsDetailInfo._stCommInfo._iContribution -= CLAN_DAIL_NEED_CONTRI;
            stDialItem.SetOssModule(OSS_MODULE_CLAN_DIAL);
            pstMainCtrl->m_stItemMgr.DropItem(0, _uiGID, stDialItem, false);
        }
        //这里不要break

    case 2:
        {
            stAns.set_dail_cnt(pstMainCtrl->m_stClanMgr.GetLeftDailCount(stPlayerBaseInfo._chVipLevel, stPlayerDetailInfo, pstMainCtrl->m_iNow, iMaxDailCnt));
            stAns.set_total_cnt(iMaxDailCnt);
            stAns.set_contri_cost(CLAN_DAIL_NEED_CONTRI);
        }
        break;

    default:
        iRet = ERROR_CLAN_DIAL_OPT;
    }

    if (iRet)
    {
        return AnsClients(iRet);
    }

    if (bNeedSaveDetail)
    {
        CVarObjectKey stKey;
        stKey.m_chDataType = DT_PLAYER_DETAIL_INFO;
        stKey.m_u64ID = _uiGID;
        CMainCtrl::m_pstMain->UpdateData(stKey, stPlayerDetailInfo, VOP_UPDATE);

        stKey.m_chDataType = DT_PLAYER_SNS_DETAIL_INFO;
        stKey.m_u64ID = _uiGID;
        CMainCtrl::m_pstMain->UpdateData(stKey, stPlayerSnsDetailInfo, VOP_UPDATE);

        pstMainCtrl->m_stNotifyMgr.Notify(_uiGID, NOTIFY_ROLE_INFO);

        if (0 == stAns.dail_cnt())
        {
            //更新活动状态
            pstMainCtrl->m_stActMgr.NotifyActListToRole(stPlayerBaseInfo, stPlayerDetailInfo);
        }
    }

    return AnsClients(RET_OK);
}

int CCmdClanDial::AnsClients(int iRet)
{
    stMsgHead.set_msgret(iRet);
    stMsgHead.set_msgtype(CSMsgDef::EMT_ANSWER);
    if (iRet != RET_OK)
    {
        pstMainCtrl->ReturnMsgHead(stMsgHead, stEnpHead);
        return Done(iRet);
    }

    stAns.set_opt(stReq.opt());
    pstMainCtrl->m_stEncodeBuf.Clear();
    pstMainCtrl->EncodePBMsg(stMsgHead, pstMainCtrl->m_stEncodeBuf);
    pstMainCtrl->EncodePBMsg(stAns, pstMainCtrl->m_stEncodeBuf);
    if (pstMainCtrl->AnswerToClient(stEnpHead, pstMainCtrl->m_stEncodeBuf,true))
    {
        CT_WARNING((""));
        return Done(RET_SYS_ERROR);
    }

    return Done(iRet);
}

CT_REGISTER_ASYNCCMD(ID_MAIN_INNER_DELETE_CLAN, CCmdDeleteClan);

int CCmdDeleteClan::Do(void* pData)
{
    if (pData != NULL)
    {
        CT_WARNING(("inner cmd CCmdDeleteClan get data"));
        return Done(RET_OK);
    }

    if (pstMainCtrl == NULL)
    {
        CT_ERROR(("mainctrl point is null"));
        return Done(RET_SYSTEM_FAIL);
    }

    CallBack(RET_OK);
    return RET_OK;
}

int CCmdDeleteClan::LogicDo(int iRet)
{
    return CallBack(iRet);
}

int CCmdDeleteClan::CallBack(int iRet)
{
    if (iRet)
    {
        HandlCallBackRet(iRet);
    }

    if (0 == _auiClanId.Size())
    {
        return Done(RET_OK);
    }

    unsigned int uiClanId = _auiClanId[0];

    int iIndex = pstMainCtrl->m_stClanMgr.GetClanIndexByClanId (uiClanId);
    if (iIndex < 0)
    {
        CT_ERROR(("CCmdDeleteClan is not exist: %d", uiClanId));
        _auiClanId.DelOneItem(0);
        return CallBack(RET_OK);
    }
    CClanEntry & stClanEntry = pstMainCtrl->m_stClanMgr.GetClanEntry(iIndex);

    if (stClanEntry._astClanMember.Size() == 0)
    {
        // 真正的删除操作.函数内部有入库操作
        pstMainCtrl->m_stClanMgr.DeleteClanInDB(stClanEntry);

        _auiClanId.DelOneItem(0);

        return CallBack(RET_OK);
    }

    unsigned int uiGid = stClanEntry._astClanMember[0]._uiGid;
    PREPARE_PLAYER_DETAIL_INFO(this, uiGid);
    PREPARE_PLAYER_SNS_DETAIL_INFO(this, uiGid);

    iIndex = pstMainCtrl->m_stPlayerDetailInfoHash.HashFind(uiGid);
    if (iIndex < 0)
    {
        CT_ERROR(("%u", uiGid));
        return CallBack(ERROR_NO_DETAIL_INFO);
    }
    CPlayerDetailInfo& stPlayerDetailInfo = pstMainCtrl->m_stPlayerDetailInfoHash[iIndex];

    iIndex = pstMainCtrl->m_stPlayerSnsDetailInfoHash.HashFind(uiGid);
    if (iIndex < 0)
    {
        CT_ERROR(("%u", uiGid));
        return CallBack(ERROR_NO_DETAIL_INFO);
    }
    CPlayerSnsDetailInfo & stPlayerSnsDetailInfo = pstMainCtrl->m_stPlayerSnsDetailInfoHash[iIndex];

    iRet = ProcOneUser(stPlayerDetailInfo, stPlayerSnsDetailInfo, stClanEntry);
    if (iRet)
    {
        CT_WARNING(("%d, %d, %d", uiClanId, uiGid, iRet));
    }

    stClanEntry._astClanMember.DelOneItem(0);

    pstMainCtrl->m_stClanMgr.UpdateToDB(uiClanId);

    PushQueue(RET_OK);
    return 0;
}

int CCmdDeleteClan::ProcOneUser (CPlayerDetailInfo& stPlayerDetailInfo, CPlayerSnsDetailInfo & stPlayerSnsDetailInfo, CClanEntry & stClanEntry)
{
    int iRet = RET_OK;
    iRet = pstMainCtrl->m_stClanMgr.DelFromClan(stPlayerDetailInfo._uiGID, stPlayerDetailInfo._stUserClan, stClanEntry);
    if (iRet)
    {
        CT_ERROR(("%d, %d, %d", stPlayerDetailInfo._uiGID, stClanEntry._uiClanId, iRet));
    }
    else
    {
        unsigned int uiGid = stPlayerDetailInfo._uiGID;

        stPlayerSnsDetailInfo._stCommInfo._uiClanId = 0;

        pstMainCtrl->m_stClanMgr.NotifyClanDeleted (uiGid);

        CVarObjectKey stKey;
        stKey.m_u64ID = uiGid;

        stKey.m_chDataType = DT_PLAYER_DETAIL_INFO;
        pstMainCtrl->UpdateData(stKey, stPlayerDetailInfo, VOP_UPDATE);

        stKey.m_chDataType = DT_PLAYER_SNS_DETAIL_INFO;
        pstMainCtrl->UpdateData(stKey, stPlayerSnsDetailInfo, VOP_UPDATE);
    }

    return 0;
}

int CCmdDeleteClan::HandlCallBackRet (int iRet)
{
    if (_auiClanId.Size() <= 0)
    {
        CT_ERROR(("%d", iRet));
        return Done(iRet);
    }

    unsigned int uiClanId = _auiClanId[0];
    int iIndex = pstMainCtrl->m_stClanMgr.GetClanIndexByClanId (uiClanId);
    if (iIndex < 0)
    {
        CT_ERROR(("%d", _auiClanId[0]));

        _auiClanId.DelOneItem(0);
        return CallBack(RET_OK);
    }

    CClanEntry & stClanEntry = pstMainCtrl->m_stClanMgr.GetClanEntry(iIndex);
    if (stClanEntry._astClanMember.Size() > 0)
    {
        CT_WARNING(("CCmdDeleteClan ret %d, %d, %d", iRet, uiClanId, stClanEntry._astClanMember[0]._uiGid));

        stClanEntry._astClanMember.DelOneItem(0);
        return CallBack(RET_OK);
    }
    else
    {
        CT_ERROR(("CCmdDeleteClan ret %d, %d", iRet, uiClanId));
    }

    return CallBack(RET_OK);
}

CT_REGISTER_ASYNCCMD(ID_MAIN_INNER_TREE_RANK, CCmdTreeRank);

int CCmdTreeRank::Do(void* pData)
{
    pstMainCtrl = CMainCtrl::m_pstMain;

    return LogicDo(RET_OK);
}

int CCmdTreeRank::LogicDo(int iRet)
{
    return CallBack(iRet);
}

int CCmdTreeRank::CallBack(int iRet)
{
    if (0 == _auiClanId.Size())
    {
        return Done(iRet);
    }

    unsigned int uiClanId = _auiClanId[0];
    if (iRet)
    {
        CT_ERROR(("%d, %d", iRet, uiClanId));
        _auiClanId.DelOneItem(0);
        return CallBack(RET_OK);
    }

    int iIndex = pstMainCtrl->m_stClanMgr.GetClanIndexByClanId (uiClanId);
    if (iIndex < 0)
    {
        CT_ERROR(("CCmdDeleteClan is not exist: %d", uiClanId));
        _auiClanId.DelOneItem(0);
        return CallBack(RET_OK);
    }
    CClanEntry & stClanEntry = pstMainCtrl->m_stClanMgr.GetClanEntry(iIndex);

    stClanEntry._stTree._stRank.Clear();
    pstMainCtrl->m_stClanMgr.UpdateToDB(stClanEntry._uiClanId);
    _auiClanId.DelOneItem(0);

    PushQueue(RET_OK);

    return RET_OK;
}
